#include "videomeetingui.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include <QPushButton>
#include <QDebug>
#include <QCloseEvent>
#include <QScrollBar>
#include <QTimer>      // 用于生成 Transaction ID (或者使用其他唯一ID方法)
#include <QMessageBox>
#include <QScrollBar>

// 外部 C 函数声明 (来自 FFmpeg)
extern "C" {
#include "libavutil/frame.h" // 包含 AVFrame 定义
}


VideoMeetingUI::VideoMeetingUI(const QString& roomId,
                               int localUserId,
                               const QString& localUserName,
                               QWidget *parent)
    : QWidget(parent),
    // m_websocket(nullptr), // <<<=== 移除
    m_roomId(roomId),
    m_localUserId(localUserId),
    m_localUserName(localUserName),
    m_mainViewUserId(-1)
{
    setWindowTitle("视频会议 - 房间: " + m_roomId);
    setMinimumSize(800, 600); // 设置最小窗口尺寸

    setupUi(); // 创建界面布局

    // --- 修改: 只创建本地 PlayImage，不启动摄像头线程 ---
    m_localPlayImage = new PlayImage(m_participantListWidget);
    m_localPlayImage->setUserInfo(m_localUserId, m_localUserName);
    m_localPlayImage->setObjectName(QString("user_%1").arg(m_localUserId));
    connect(m_localPlayImage, &PlayImage::clicked, this, &VideoMeetingUI::onParticipantClicked);
    m_participantListLayout->insertWidget(0, m_localPlayImage);
    // --- 修改结束 ---

    // --- 添加测试用户 ---
    int testUserId = -99; // 给一个唯一的负数ID
    QString testUserName = "Test User";
    PlayImage* testPlayImage = new PlayImage(m_participantListWidget);
    testPlayImage->setUserInfo(testUserId, testUserName);
    testPlayImage->setObjectName(QString("user_%1").arg(testUserId));
    testPlayImage->setBlackBackground(); // 测试用户显示黑屏
    connect(testPlayImage, &PlayImage::clicked, this, &VideoMeetingUI::onParticipantClicked);
    m_participants.insert(testUserId, testPlayImage); // 添加到 map 中
    m_participantListLayout->addWidget(testPlayImage); // 添加到列表末尾
    QTimer::singleShot(0, this, [this]() { setMainView(m_localUserId); });
}

VideoMeetingUI::~VideoMeetingUI()
{
    qDebug() << "VideoMeetingUI destructor called.";
}

void VideoMeetingUI::setupUi()
{
    m_mainLayout = new QHBoxLayout(this);
    m_mainLayout->setContentsMargins(5, 5, 5, 5);
    m_mainLayout->setSpacing(5);

    // --- 左侧参与者列表 ---
    m_participantScrollArea = new QScrollArea(this);
    m_participantScrollArea->setWidgetResizable(true); // 允许内部 Widget 调整大小
    m_participantScrollArea->setMinimumWidth(160); // 设置最小宽度
    m_participantScrollArea->setMaximumWidth(240); // 设置最大宽度
    // m_participantScrollArea->setStyleSheet("QScrollArea { border: 1px solid lightgray; }");

    m_participantScrollArea->setStyleSheet("QScrollArea { border: none; }"); // 去掉边框可能更好看
    m_participantScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 隐藏水平滚动条

    m_participantListWidget = new QWidget(); // 滚动区域内的容器 Widget
    m_participantListLayout = new QVBoxLayout(m_participantListWidget); // 垂直布局放 PlayImage
    m_participantListLayout->setContentsMargins(0, 0, 0, 0); // 列表内部无边距
    m_participantListLayout->setSpacing(3); // 缩略图之间的间距

    m_participantListLayout->setAlignment(Qt::AlignTop);

    m_participantScrollArea->setWidget(m_participantListWidget);
    m_mainLayout->addWidget(m_participantScrollArea, 0); // 修改: 比例设为 0，让它根据内容和宽度限制来确定大小

    // --- 右侧主区域 ---
    QWidget* rightWidget = new QWidget(this);
    m_rightAreaLayout = new QVBoxLayout(rightWidget);
    m_rightAreaLayout->setContentsMargins(0, 0, 0, 0);
    m_rightAreaLayout->setSpacing(5);

    // 主视频视图容器
    m_mainViewContainer = new QWidget(rightWidget);
    // m_mainViewContainer->setStyleSheet("QWidget { background-color: black; border: 1px solid gray; }"); // 黑色背景和边框
    m_mainViewContainer->setStyleSheet("QWidget { background-color: black; border: none; }"); // 移除边框
    m_mainViewContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 占据尽可能大的空间
    // 给容器也加一个布局，方便放入 PlayImage
    QVBoxLayout* mainViewInternalLayout = new QVBoxLayout(m_mainViewContainer);
    mainViewInternalLayout->setContentsMargins(0,0,0,0);
    m_rightAreaLayout->addWidget(m_mainViewContainer, 1); // 视频区域占一份伸缩比例

    // 底部控制按钮区域
    QWidget* controlWidget = new QWidget(rightWidget);
    controlWidget->setMaximumHeight(40); // 限制按钮区域高度
    m_controlButtonLayout = new QHBoxLayout(controlWidget);
    m_controlButtonLayout->setContentsMargins(0, 0, 0, 0);
    m_controlButtonLayout->setSpacing(10);
    m_controlButtonLayout->addStretch(); // 按钮居中

    m_cameraButton = new QPushButton("关闭摄像头", controlWidget);
    connect(m_cameraButton, &QPushButton::clicked, this, &VideoMeetingUI::onCameraControlButtonClicked);
    m_controlButtonLayout->addWidget(m_cameraButton);

    m_micButton = new QPushButton("关闭麦克风", controlWidget);
    connect(m_micButton, &QPushButton::clicked, this, &VideoMeetingUI::onMicControlButtonClicked);
    m_controlButtonLayout->addWidget(m_micButton);

    m_shareButton = new QPushButton("屏幕共享", controlWidget);
    m_shareButton->setEnabled(false); // 暂时禁用
    connect(m_shareButton, &QPushButton::clicked, this, &VideoMeetingUI::onShareScreenControlButtonClicked);
    m_controlButtonLayout->addWidget(m_shareButton);

    m_chatButton = new QPushButton("聊天", controlWidget);
    m_chatButton->setEnabled(false); // 暂时禁用
    connect(m_chatButton, &QPushButton::clicked, this, &VideoMeetingUI::onChatControlButtonClicked);
    m_controlButtonLayout->addWidget(m_chatButton);

    m_controlButtonLayout->addStretch(); // 按钮居中

    m_rightAreaLayout->addWidget(controlWidget); // 添加按钮区域

    // m_mainLayout->addWidget(rightWidget, 4); // 右侧占四份伸缩比例
    m_mainLayout->addWidget(rightWidget, 1); // 修改: 右侧比例设为 1，让它占据剩余空间
}

// 添加用户 (通常由 Janus 的 'event' -> 'publishers' 触发)
void VideoMeetingUI::addUser(int userId, const QString& userName)
{
    if (userId == m_localUserId || m_participants.contains(userId)) {
        qWarning() << "Attempted to add existing or local user:" << userId << userName;
        return;
    }

    qInfo() << "Adding user:" << userId << userName;
    PlayImage* newUserImage = new PlayImage(m_participantListWidget); // 父控件是列表容器
    newUserImage->setUserInfo(userId, userName);
    newUserImage->setObjectName(QString("user_%1").arg(userId));
    newUserImage->setBlackBackground(); // 初始设置为黑屏，等待视频流
    connect(newUserImage, &PlayImage::clicked, this, &VideoMeetingUI::onParticipantClicked);

    m_participants.insert(userId, newUserImage);
    m_participantListLayout->addWidget(newUserImage); // 添加到列表末尾
    updateParticipantListOrder(); // 确保顺序正确
}

// 删除用户 (通常由 Janus 的 'event' -> 'leaving' 或 'unpublished' 触发)
void VideoMeetingUI::removeUser(int userId)
{
    if (!m_participants.contains(userId)) {
        qWarning() << "Attempted to remove non-existent user:" << userId;
        return;
    }

    qInfo() << "Removing user:" << userId;
    PlayImage* imageToRemove = m_participants.value(userId);

    // 如果要移除的用户正在主视图显示
    if (userId == m_mainViewUserId) {
        // 清空主视图
        if (m_mainViewPlayImage) {
            m_mainViewContainer->layout()->removeWidget(m_mainViewPlayImage);
            m_mainViewPlayImage->setParent(nullptr); // 清除父控件
            // 不需要 delete m_mainViewPlayImage，因为它就是 imageToRemove
            m_mainViewPlayImage = nullptr;
        }
        m_mainViewUserId = -1;
            // 可以选择显示本地画面或保持黑屏
        // setMainView(m_localUserId);
    }

    // 从参与者列表布局中移除
    m_participantListLayout->removeWidget(imageToRemove);
    // 从 Map 中移除
    m_participants.remove(userId);
    // 删除 PlayImage 对象
    imageToRemove->deleteLater(); // 使用 deleteLater 更安全

    updateParticipantListOrder(); // 更新列表
}


void VideoMeetingUI::onParticipantClicked(int userId)
{
    qDebug() << "Participant clicked in UI:" << userId;
    setMainView(userId);
}

// 将指定用户设置为主画面
void VideoMeetingUI::setMainView(int userId)
{
    if (userId == m_mainViewUserId) {
        qDebug() << "User" << userId << "is already in main view.";
        return;
    }

    PlayImage* newMainImage = nullptr;
    bool isLocal = (userId == m_localUserId);

    if (isLocal) {
        newMainImage = m_localPlayImage;
    } else if (m_participants.contains(userId)) {
        newMainImage = m_participants.value(userId);
    }

    if (!newMainImage) {
        qWarning() << "Cannot set main view: User ID not found" << userId;
        return;
    }

    qDebug() << "Setting main view to user:" << userId;
    this->setEnabled(false); // 界面切换时禁用交互，防止误操作

    // 1. 将当前主视图控件（如果存在且不是即将成为主视图的控件）移回左侧列表
    if (m_mainViewPlayImage && m_mainViewPlayImage != newMainImage) {
        int oldMainViewUserId = m_mainViewUserId;
        PlayImage* oldMainImage = m_mainViewPlayImage;

        qDebug() << "Moving user" << oldMainViewUserId << "from main view to list.";
        m_mainViewContainer->layout()->removeWidget(oldMainImage);
        oldMainImage->setParent(m_participantListWidget); // 重新设置父对象

        // --- 修改: 使用 insertWidget 将其插回正确位置 ---
        int insertIndex = 1; // 默认插入到本地用户之后
        if (oldMainViewUserId == m_localUserId) {
            insertIndex = 0; // 本地用户回到索引0
        } else {
            // 可以根据需要找到其他用户的顺序来插入，或者简单插入到本地用户后
            // 这里我们先简单插入到索引 1
            // 注意：如果列表为空（除了本地用户），索引可能需要调整
            if (m_participantListLayout->count() > 0) {
                insertIndex = 1;
            } else {
                insertIndex = 0; // 如果列表空了就插到0
            }
            // 更健壮的方式是遍历 m_participants map 的 key (userId) 来决定顺序
        }
        m_participantListLayout->insertWidget(insertIndex, oldMainImage);
        // --- 修改结束 ---

        oldMainImage->show(); // 确保在列表中可见
        m_mainViewPlayImage = nullptr; // 清空指针
        m_mainViewUserId = -1;         // 重置 ID
    }

    // 2. 将新的主视图控件从左侧列表移动到右侧主视图容器
    if (newMainImage->parent() == m_participantListWidget) { // 确认它确实在左侧列表
        qDebug() << "Moving user" << userId << "from list to main view.";
        m_participantListLayout->removeWidget(newMainImage); // 从左侧布局移除
        newMainImage->setParent(m_mainViewContainer); // 设置新父对象
        m_mainViewContainer->layout()->addWidget(newMainImage); // 添加到右侧布局
        newMainImage->show(); // 确保可见
        // --- 添加: 手动触发标签位置更新 ---
        QTimer::singleShot(0, newMainImage, [newMainImage](){
            newMainImage->updateLabelPosition(); // 延迟调用以确保尺寸已更新
        });
        // --- 添加结束 ---
    } else {
        qWarning() << "New main image" << userId << "was not in the participant list widget parent.";
        // 可能 newMainImage 就是 m_mainViewPlayImage，在上面的 if 中未被处理
        if(m_mainViewPlayImage == newMainImage){
            qDebug() << "New main image is the same as the old one (should not happen if userId != m_mainViewUserId)";
            // 如果是这种情况，则不需要移动，但代码逻辑应该阻止这种情况
        } else {
            // 控件不在预期位置，可能是个错误
        }
    }


    // 3. 更新状态变量
    m_mainViewPlayImage = newMainImage;
    m_mainViewUserId = userId;

    // 4. 更新左侧列表顺序（以防万一，并确保间距）
    updateParticipantListOrder();

    // 5. 确保滚动区域是最新的
    // QTimer::singleShot(10, m_participantScrollArea, &QScrollArea::ensureWidgetVisible); // 这个可能不准确
    m_participantScrollArea->widget()->updateGeometry(); // 更新滚动区域内部 widget 的几何形状

    this->setEnabled(true); // 重新启用界面
}


void VideoMeetingUI::updateRemoteUserFrame(int userId, AVFrame* frame)
{
    if (m_participants.contains(userId)) {
        PlayImage* targetImage = m_participants.value(userId);
        if (targetImage) {
            targetImage->repaint(frame); // 传递帧给 PlayImage
        }
        else {
            qWarning() << "updateRemoteUserFrame: PlayImage not found for user" << userId;
            // 帧没有被使用，需要释放
            av_frame_unref(frame);
            av_frame_free(&frame);
        }
    }
    else {
        qWarning() << "updateRemoteUserFrame: User ID not found in participants map:" << userId;
        // 帧没有被使用，需要释放
        av_frame_unref(frame);
        av_frame_free(&frame);
    }
    // 注意：PlayImage::repaint 现在不负责释放帧，所以在这里释放
    // 如果 targetImage->repaint(frame) 调用了，它内部也不应释放
    // 但是，如果 repaint 是异步的，这里立即释放可能有问题
    // 假设 repaint 是同步的或者 PlayImage 内部会处理好（但我们的 PlayImage 实现没有）
    // 最安全的方式是 PlayImage 内部在渲染完后发出信号，或者我们信任调用者会管理好
    // 目前按照约定：此函数负责释放传入的 frame
    if (frame) { // 再次检查，防止上面逻辑出错导致重复释放
        av_frame_unref(frame); // 清空数据引用
        av_frame_free(&frame); // 释放结构体本身
    }
}

// 处理本地摄像头帧数据
void VideoMeetingUI::onLocalFrameReady(AVFrame* frame)
{
    if (m_localPlayImage) {
        m_localPlayImage->repaint(frame);
        // 此函数负责释放 CCamera::frameReady 发出的克隆帧
        av_frame_unref(frame); // ReadThread 读取的帧需要释放
        av_frame_free(&frame); // 释放 AVFrame 结构本身
    } else {
        av_frame_unref(frame);
        av_frame_free(&frame);
    }
}

// 更新左侧列表顺序，确保本地用户在最上面
void VideoMeetingUI::updateParticipantListOrder()
{
    // 1. 从布局中移除所有 PlayImage 控件，但保留指针
    QList<PlayImage*> allImages;
    if(m_localPlayImage && m_localPlayImage->parentWidget() == m_participantListWidget) {
        allImages.append(m_localPlayImage);
        m_participantListLayout->removeWidget(m_localPlayImage);
    }
    QMapIterator<int, PlayImage*> i(m_participants);
    while (i.hasNext()) {
        i.next();
        PlayImage* img = i.value();
        if (img && img->parentWidget() == m_participantListWidget) {
            allImages.append(img);
            m_participantListLayout->removeWidget(img);
        }
    }

    // 2. 对非本地用户进行排序（如果需要，例如按加入时间或名称）
    // 这里我们暂时不排序，按 m_participants 的顺序

    // 3. 将本地用户（如果存在于列表中）插入到索引 0
    if (m_localPlayImage && allImages.contains(m_localPlayImage)) {
        m_participantListLayout->insertWidget(0, m_localPlayImage);
        allImages.removeAll(m_localPlayImage); // 从待添加列表中移除
    } else if (m_localPlayImage) {
        // 本地用户不在列表里（可能在主视图）
    }

    // 4. 将其他用户按顺序添加回去
    for (PlayImage* img : allImages) {
        m_participantListLayout->addWidget(img); // 依次添加到末尾
    }

    // 5. 更新布局
    m_participantListLayout->update(); // 请求布局更新
    m_participantListWidget->adjustSize(); // 调整容器 widget 大小以适应内容
}



// --- 控制按钮槽函数 onXXXControlButtonClicked() 不变 (只改 UI 文本，不处理摄像头/麦克风逻辑) ---
// 注意：摄像头/麦克风的开关状态 m_isCameraOn, m_isMicOn 现在只反映 UI 状态
// 实际的开关逻辑需要通过其他途径（例如信号）通知 CCamera 或音频模块
void VideoMeetingUI::onCameraControlButtonClicked()
{
    m_isCameraOn = !m_isCameraOn;
    if (m_isCameraOn) {
        m_cameraButton->setText("关闭摄像头");
        // TODO: 发出信号通知外部逻辑打开摄像头数据流（如果之前关闭了）
        // 例如 emit requestLocalVideo(true);
    }
    else {
        m_cameraButton->setText("打开摄像头");
        if (m_localPlayImage) m_localPlayImage->setBlackBackground(); // UI 上显示黑屏
        // TODO: 发出信号通知外部逻辑关闭摄像头数据流
        // 例如 emit requestLocalVideo(false);
    }
}

void VideoMeetingUI::onMicControlButtonClicked()
{
    m_isMicOn = !m_isMicOn;
    if (m_isMicOn) {
        m_micButton->setText("关闭麦克风");
        // TODO: 开启本地麦克风采集 + 发送 Janus 消息通知服务器启用音频流
    } else {
        m_micButton->setText("打开麦克风");
        // TODO: 关闭本地麦克风采集 + 发送 Janus 消息通知服务器禁用音频流
    }
}

void VideoMeetingUI::onShareScreenControlButtonClicked()
{
    // TODO: 实现屏幕共享逻辑
    QMessageBox::information(this, "提示", "屏幕共享功能尚未实现。");
}

void VideoMeetingUI::onChatControlButtonClicked()
{
    // TODO: 实现聊天区域的显示/隐藏
    QMessageBox::information(this, "提示", "聊天功能尚未实现。");
}


void VideoMeetingUI::closeEvent(QCloseEvent *event)
{
    qDebug() << "VideoMeetingUI closeEvent triggered.";
    // 发出关闭信号，通知 Widget
    emit closed();
    // 可以在这里发送离开 Janus 房间的消息
    // ... send leave/detach message ...
    QWidget::closeEvent(event); // 接受关闭事件
}
